<?php
	require_once("htons-ntohs.php");
	require_once("protocoldef.php");

	// 开始时间
	$start=microtime(true);
	// 重试次数
	define("RETRY",5);

	/// 格式:uint|md5|uint|uint64
	//  适用于地点话题(pti)
	//error_reporting(0);
	class InsertCmd{
	 public $cmd	= array(
		"poi_id" => array(
			"type" 	=> "uint32",
			"value" => 0,
			"repeat" => 0),
		"create_time" => array(
			"type" 	=> "uint32",
			"value" => 0,
			"repeat" => 0),
		"msg_id" => array(
			"type" 	=> "uint64",
			"value" => 0,
			"repeat" => 1),
		"end"	 => array(
			"type"  => "char",
			"value" => 3,
			"repeat" => 0)
		);
	}
	
	$DBINFO=array(
		0 => array(		// pti 地点话题(ptopic)
			"mongoserver" => "10.10.83.7",
			"mongoport"   => 65431,
			"idxserver"   => "10.10.83.30",
			"idxport"     => 58017,
			"packlength"  => 49,
			"dbname" => "db2_pti_",
			"dbnum"  => 10,
			"tbname" => "t_pti_",
			"tbnum"  =>  1,
			"name"	 => "ptopic",
			"field"  => array(		
				0 => "poi_id",
				1 => "title",
				2 => "create_time",
				3 => "msg_id"
			)
		)
	);

	$totalrecord=1;
	foreach($DBINFO as $dbkey => $dbvalue)
	{
		$mongoserver	= $DBINFO[$dbkey]["mongoserver"];
		$mongoport	= $DBINFO[$dbkey]["mongoport"];
		$idxserver	= $DBINFO[$dbkey]["idxserver"];
		$idxport	= $DBINFO[$dbkey]["idxport"];
		$packlength	= $DBINFO[$dbkey]["packlength"];
		$dbnum		= $DBINFO[$dbkey]['dbnum'];
		$recordname	= $DBINFO[$dbkey]['name'];
		$recordnum	= 0;

		// 初始化头
		$uvheader=new UVHEADER();
		$uvheader->header["len"]["value"]	= $packlength;
		$uvheader->header["cmd"]["value"]	= 3;
		uvpack($uvheader->header);

		// 预先声明InsertCmd、RspdInsertCmd对象
		$insertcmd	= new InsertCmd();
		// 貌似可以不要
		//$rspdinsertcmd	= new RspdInsertCmd();

		// 连接Mongo
		$server="mongodb://".$mongoserver.":".$mongoport;
		$conn=new Mongo($server);
		if($conn===false)
		{
			print "Mongo() fail<br />";
			exit(-1);
		}

		// 与索引系统建立socket长连接
		$sockfd=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
		if($sockfd==false)
		{
			printf("socket_create fail.[%d-%s]<br />",socket_last_error(),socket_strerror(socket_last_error()));
			exit(-1);
		}

		if((socket_connect($sockfd,$idxserver,$idxport))==false)
		{
			printf("socket_connect fail.[%d-%s]<br />",socket_last_error(),socket_strerror(socket_last_error()));
			exit(-1);
		}


		for($i=0;$i<$dbnum;$i++)
		{
			$dbname = $DBINFO[$dbkey]['dbname']."0_".$i;

			$db=$conn->selectDB($dbname);
			printf("dbname = %s dbnum = %d start:\n",$dbname,$i);

			// 获取四个索引字段的字段名称,顺序为:poi_id,title,create_time,msg_id
			$key1	= $DBINFO[$dbkey]['field'][0];
			$key2	= $DBINFO[$dbkey]['field'][1];
			$key3	= $DBINFO[$dbkey]['field'][2];
			$key4	= $DBINFO[$dbkey]['field'][3];

			$tbnum=$DBINFO[$dbkey]['tbnum'];
			for($j=0;$j<$tbnum;$j++)
			{
				$tbname = $DBINFO[$dbkey]['tbname'].$j;

				$collect=$db->selectCollection($tbname);
				printf("tbname = %s tbnum = %d start:\n",$tbname,$j);
				
				$cursor=$collect->find();
				$num=1;
				foreach($cursor as $obj)
				{
					printf("md5 = [%s]\n",md5($obj[$key2]));
					$md5bin=md5($obj[$key2],true);

					for($n=0;$n<16;$n++)
					{
						printf("%02x ",ord($md5bin[$n]));
						if(($n!=0)&&(($n+1)%8==0))
							printf("\n");
					}

					$insertcmd->cmd["poi_id"]["value"]		= $obj[$key1];
					$insertcmd->cmd["create_time"]["value"]		= $obj[$key3];
					$insertcmd->cmd["msg_id"]["value"]		= $obj[$key4];

					printf("recordname = %s totalrecord = %u current num = %u %s = %lu %s = %lu %s = %lu\n",$recordname,$totalrecord,$num,$key1,$obj[$key1],$key3,$obj[$key3],$key4,$obj[$key4]);
					$num++;
					$totalrecord++;
					$recordnum++;

					uvpack($insertcmd->cmd);

					// 头部格式及参数值
					$FORMAT	=	"CSSSCL";
					$PARA[0]=	$uvheader->header["begin"]["value"];
					$PARA[1]=	$uvheader->header["len"]["value"];
					$PARA[2]=	$uvheader->header["ver"]["value"];
					$PARA[3]=	$uvheader->header["cmd"]["value"];
					$PARA[4]=	$uvheader->header["reserve"]["value"];
					// poi_id
					$PARA[5]=	$insertcmd->cmd["poi_id"]["value"];
					$temp=call_user_func_array("pack",array_merge((array)$FORMAT,$PARA));

					$bindata=$temp.$md5bin;
				
					// 判断字节数是否是8的整倍数，如果是，则需要按实际情况进行换位
					$flag		= 0;
					$addafter32	= "";
					$addbefore32	= "";
					$PARA1		= array();
					$FORMAT1	= "";
					foreach($insertcmd->cmd as $key => $value)
					{
						if(($key=="create_time")||($key=="msg_id"))
						{
							$idtype=$insertcmd->cmd[$key]["type"];
							if($uvbyte[$idtype]==8)
							{	
								$temp1=decbin($insertcmd->cmd[$key]["value"]);
								$before32	= substr($temp1,0,-32);
								$after32	= substr($temp1,-32);
								$before32	= bindec($before32);
								$after32	= bindec($after32);
								$PARA1[]		= $after32;
								$PARA1[]		= $before32;
								$FORMAT1		= $FORMAT1."LL";	
								// 判断是否需要重复
								if($insertcmd->cmd[$key]["repeat"]==1)
								{
									$flag=1;
									$addafter32	= $after32;
									$addbefore32	= $before32;
								}
							}
							else
							{
								$PARA1[]		= $insertcmd->cmd[$key]["value"];
								$FORMAT1		= $FORMAT1."L";	
							}
						}
					}

					if($flag==1)
					{
						$PARA1[]	= $addafter32;
						$PARA1[]	= $addbefore32;
						$FORMAT1	= $FORMAT1."LL";
					}

					
					$PARA1[]	= $insertcmd->cmd["end"]["value"];
					$FORMAT1	= $FORMAT1."C";
					$temp=call_user_func_array("pack",array_merge((array)$FORMAT1,$PARA1));
					$bindata=$bindata.$temp;
					$temp=$bindata;

					for($n = 0;$n < $packlength; $n++)
					{
						printf("%02x ",ord($temp[$n]));
						if(($n!=0)&&(($n+1)%8==0))
							printf("\n");

					}

					printf("\n");

	
					$buflen	= $packlength;
					$retry	= 1;
					$ret	= 0;
					while($retry<=RETRY)
					{
						$ret=socket_send($sockfd,$temp,$buflen,NULL);
						//$ret=socket_write($sockfd,$temp,$buflen);
						if($ret==$buflen)
						{
							break;
						}

						$retry++;
					}

					if($retry>RETRY)
					{
						printf("send data fail,sockfd = %s,totalrecord = %u,[%d-%s]\n",$sockfd,$totalrecord,socket_last_error(),socket_strerror(socket_last_error()));
						continue;
					}


					$temp="";
					$ret=socket_recv($sockfd,$temp,13,NULL);
					if(($ret===false)||($ret!==13))
					{
						printf("recv data fail,sockfd = %s,totalrecord = %u,[%d-%s]\n",$sockfd,$totalrecord,socket_last_error(),socket_strerror(socket_last_error()));
						continue;
					}

					$temp1=unpack("C/n/n/n/C/Ncode/C",$temp);
					if($temp["code"]!=0)
					{
						printf("unpack data fail,sockfd = %s,totalrecord = %u,[%d-%s]\n",$sockfd,$totalrecord,socket_last_error(),socket_strerror(socket_last_error()));
						continue;
					}	

					//if($totalrecord>=3)
					//	exit;
 
					unset($PARA);
					unset($FORMAT);
					unset($md5bin);
				} // foreach($cursor as $obj)
			} // for($j=0;$j<$tbnum;$j++)
			printf("\n");
		} // for($i=0;$i<$dbnum;$i++)
		socket_close($sockfd);
		$conn->close();
		printf("recordname = [%send],recordnum = [%lu]\n\n",$recordname,$recordnum);
	} // foreach($DBINFO as $dbkey => $dbvalue)
	

	echo "TOTAL TIME : ".(microtime(true)-$start)."\n\n";
?>
